/**
 * 
 */
package due.pc.pcshoot.entity;

import java.util.ArrayList;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;

import android.content.Context;

/**
 * @author manhhung.vu
 *
 */
public class Ball extends Sprite 
{
	//===============================================================/
	//Constants
	//===============================================================/
	public static final String BALL_IMAGEPATH = "gfx/kugel_test.png";
	public static final int BALL_WIDTH = 24;
	public static final int BALL_HEIGHT = 24; //32
	
	private static ArrayList<Ball> CACHED_BALLS = new ArrayList<Ball>();
	
	
	//===============================================================/
	//Fields
	//===============================================================/
	private BallState mState;
	private IBallStateChangeListener mBallStateChangeListener;
	
	//===============================================================/
	//Constructors
	//===============================================================/
	public Ball(float pX, float pY, TextureRegion pTextureRegion) 
	{
		super(pX, pY, pTextureRegion);
		mState = BallState.READY;
	}
	
	//===============================================================/
	//Inherited Methods
	//===============================================================/
	
	//===============================================================/
	//Methods
	//===============================================================/
	public void reset()
	{
		clearEntityModifiers();
		clearUpdateHandlers();
		mState = BallState.READY;
	}
	
	//===============================================================/
	//Getters & Setters
	//===============================================================/
	public BallState getState() {
		return mState;
	}
	
	public void setState(BallState pState) {
		this.mState = pState;
		if (mBallStateChangeListener != null) {
			mBallStateChangeListener.onBallStateChanged(pState, this);
		}
	}
	
	public void setBallStateChangeListener(IBallStateChangeListener pBallStateChangeListener) {
		this.mBallStateChangeListener = pBallStateChangeListener;
	}
	
	//===============================================================/
	//Static Methods                 
	//===============================================================/
	private static Ball create(float pX, float pY, Engine pEngine, Context pContext)
	{
		Texture ballTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		TextureRegion ballTextureRegion = TextureRegionFactory.createFromAsset(
				ballTexture, pContext, BALL_IMAGEPATH, 0, 0);
		
		pEngine.getTextureManager().loadTexture(ballTexture);
		
		Ball ball = new Ball(pX, pY, ballTextureRegion);
		ball.setWidth(BALL_WIDTH);
		ball.setHeight(BALL_HEIGHT);
		return ball;
	}
	
	public static Ball createBall(float pX, float pY, Engine pEngine, Context pContext)
	{
		Ball ball = getReadyBall();
		
		if (ball == null) 
		{
			ball = create(pX, pY, pEngine, pContext);
			CACHED_BALLS.add(ball);
		}
		else ball.setPosition(pX, pY);
		
		return ball;
	}
	
	private static Ball getReadyBall() 
	{
		for (Ball ball : CACHED_BALLS) {
			if (ball.mState.equals(BallState.READY)) return ball;
		}
		return null;
	}
	
	public static void preload(int pAmong, Engine pEngine, Context pContext) 
	{
		for (int i = 0; i < pAmong; i++) {
			CACHED_BALLS.add(create(0, 0, pEngine, pContext));
		}
	}
	
	//===============================================================/
	//Inner Classes
	//===============================================================/
	public static enum BallState 
	{
		READY,
		FIRED,
		HIT,
		MISSED
	}
	
	public static interface IBallStateChangeListener {
		public void onBallStateChanged(BallState pState, Ball pBall);
	}
}
